/**
 * =====================================================================================
 *
 *      @file:  cache_vector.h
 *
 *    	@brief:  手工实现的C语言vector类，类似于STL std::vecotr，此处是接口声明
 *
 *      @version:  1.0
 *      Created:  2010年04月08日 15时49分44秒
 *      Revision:  none
 *      Compiler:  gcc -Wall -Wextra vector.h
 *
 *      @author:  easyeagel (LiuGuangBao), easyeagel@gmx.com
 *      Company:  简单C++ - www.easycpp.org
 *
 * =====================================================================================
 */

#ifndef M_magus_cache_vector_h
#define M_magus_cache_vector_h


#ifdef __cplusplus
#include<cstring>
#include<cstdlib>
extern "C"
{
#else
#include<string.h>
#include<stdlib.h>
#endif

#define MtoViodPoint(value) ((void*)(&value))

#define MdefineInnerCompare(FunName, InnerType)\
InnerType FunName(const void* l, const void* r)\
{\
	if(*(InnerType*)l<*(InnerType*)r)\
	{\
		return -1;\
	} else if (*(InnerType*)l==*(InnerType*)r) {\
		return 0;\
	}\
\
	return 1;\
}

#define MdefineInnerCopy(FunName, InnerType)\
void FunName(void* dest, const void* src)\
{\
	*(InnerType*)dest=*(InnerType*)src;\
}

typedef int (*compare_fun_t)(const void* l, const void* r);
typedef void (*copy_fun_t)(void* dest, const void* src);
typedef void (*destroy_fun_t)(void* v);


typedef struct vector_t
{
	size_t index; /**< 下一个可用的位置 */
	size_t capacity;
	size_t step;
	void* vector;
	compare_fun_t compare; /**< 一个比较函数，问题需要手工设置，没有默认值 */
	copy_fun_t copy; /**< 一个复制函数，问题需要手工设置，没有默认值 */
	destroy_fun_t destroy;
}vector_t;

/**
 * @brief 新建一个vector_t对象
 * @param s 容器内一个元素的大小，依字节计算
 * @param c 容器的初始容量，依元素计算
 * @return NULL，如果没有创建成功；创建的容器
 */
vector_t* vct_create(size_t s,  size_t c);

/**
 * @brief 为vector_t设置一个比较函数
 * @param vct 需要设置的数组
 * @param compare 一个比较函数
 * @see compare_fun_t
 */
void vct_fun_compare(vector_t* vct, compare_fun_t compare);

/**
 * @brief 为vector_t设置一个比较函数
 * @param vct 需要设置的数组
 * @param copy 一个复制函数
 * @see copy_fun_t
 */
void vct_fun_copy(vector_t* vct,  copy_fun_t copy);

/**
 * @brief 销毁一个vector_t对象
 * @param vct 需要销毁的对象
 */
void vct_free(vector_t* vct);

/**
 * @brief 调整一个数组的容量
 * @param vct 需要调整的数组
 * @param c 把容量调整到多少
 * @note 由于内部使用realloc，所以当分配不成功时，会释放原内存
 */
vector_t* vct_recapacity(vector_t *vct, size_t c);

/**
 * @brief 在数组后面追加一个元素
 * @param vct 在哪个数组后面追加
 * @param d 追加的元素
 * @note 追加元素可能需要调整容量，所以可能会失败；同时复制d的内容需要调用copy函数
 */
void vct_pushback(vector_t* vct, void* d);

/**
 * @brief 找到第N个元素
 * @param vct 在哪儿查找
 * @param idx 哪个位置的元素
 * @return NULL：如果没有找到；找到元素的地址
 */
void* vct_index(vector_t* vct, size_t idx);

/** 
* @brief 顺序查找一个元素，依这个元素的值
* 
* @param vct 相应的数组
* @param d 需要查找的值
* 
* @return 查找到的元素的地址；或者NULL，没有找到
*/
void* vct_find(vector_t* vct, void* d);

/** 
* @brief 使用快速排序算法对数据进行排序
* 
* @param vct 相应的数组
*/
void vct_qsort(vector_t* vct);

/** 
* @brief 使用二分查找算法查找一个元素，依据它的值
* 
* @param vct 相应的数组
* @param d 需要查找的值
* 
* @return 查找到的元素的地址；或者NULL，表没有找到
*
* @note 使用本函数之前应该对数组进行排序，并排序时使用的比较规则与查找时的一样
*		本函数依赖于compare函数
*/
void* vct_bsearch(vector_t* vct, void*d);

/* 单调函数的宏实现版本 */
#ifndef M_vector_implement_file
#define vct_fun_compare(vct, fun) ((void)((vct)->compare=(fun)))
#define vct_fun_copy(vct, fun) ((void)((vct)->copy=(fun)))
#define vct_fun_destroy(vct, fun) ((void)((vct)->destroy=(fun)))
#define vct_qsort(vct) qsort((vct)->vector, (vct)->index, (vct)->step, (vct)->compare)
#define vct_bsearch(vct, data) bsearch((data), (vct)->vector, (vct)->index, (vct)->step, (vct)->compare)
#endif



#ifdef __cplusplus
}
#endif

#endif /* M_magus_vector_h */

